﻿using Newtonsoft.Json;
using System;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace UIControllTool {
    public class Tool {
        public static string FunctionDllName;
        public static Color GetColorBy16(string ColorString16, int Alpha = 255) {
            string R;
            string G;
            string B;
            R = ColorString16.Substring(0, 2);
            G = ColorString16.Substring(2, 2);
            B = ColorString16.Substring(4, 2);
            return Color.FromArgb(Alpha, Convert.ToInt32(R, 16), Convert.ToInt32(G, 16), Convert.ToInt32(B, 16));
        }

        public static T GetControlByForm<T>(Control form, string controlName) where T : Control, new() {
            foreach (Control control in form.Controls) {
                if (control.Name == controlName && control is T targetControl) {
                    return targetControl;
                } else {
                    T foundControl = GetControlByForm<T>(control, controlName);
                    if (foundControl != null) {
                        return foundControl;
                    }
                }
            }
            return null;
        }
        public static void SerializeToFile<T>(T obj, string filePath) {
            var settings = new JsonSerializerSettings {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            };
            string json = JsonConvert.SerializeObject(obj, settings);
            File.WriteAllText(filePath, json);
        }

        public static T DeserializeFromFile<T>(string filePath) {
            if (File.Exists(filePath)) {
                string json = File.ReadAllText(filePath);
                return JsonConvert.DeserializeObject<T>(json);
            }
            return default(T);
        }
        public static Hashtable CreateObjectBySpecific() {
            Assembly assembly = Assembly.LoadFrom(FunctionDllName+".dll"); // 假设已经加载了包含所需类的 DLL

            // 查找具有特定特性的类型
            Type[] types = assembly.GetTypes();
            Hashtable specialObjects = new Hashtable();
            foreach (Type type in types) {
                object[] attributes = type.GetCustomAttributes(typeof(ToolCreateUserControlAttribute), false);
                if (attributes.Length > 0) {
                    object instance = Activator.CreateInstance(type);
                    // 创建对象并添加到 Hashtable
                    InitUserControl initUserControl= instance as InitUserControl;
                    specialObjects.Add(initUserControl.FunctionName, instance);
                }
            }

            

            return specialObjects;
        }
        public static Hashtable Functions;
        public static object FormWin;
        public static void FormLoad(Form form) {

            Functions = CreateObjectBySpecific();
            foreach (string item in Functions.Keys) {
                //加载类的静态内容
                InitUserControl initUserControl = Functions[item] as InitUserControl;
                //拿到使用特定的初始化方法
                InitUserControlInterface initUserControlInterface = Functions[item] as InitUserControlInterface;
                string Name = getJsonFile(initUserControl.FunctionName);
                if (File.Exists(Name)) {
                    //利用静态内容重构对象内容,数据组装到数据层
                    InitUserControlData initUserControlData = initUserControl as InitUserControlData;
                    initUserControlData = Tool.DeserializeFromFile<InitUserControlData>(Name);
                    CopyObject(initUserControl, initUserControlData);
                }
                
                //利用数据驱动图形界面
                initUserControlInterface.InitUserControlImpl();
            }

            //form
            StackTrace stackTrace = new StackTrace(true); // true表示包含文件名、行号等详细信息
            StackFrame callerFrame = stackTrace.GetFrame(1); // 0是当前方法，1是调用者
            MethodBase callerMethod = callerFrame.GetMethod();
            Assembly callerAssembly = callerMethod.DeclaringType.Assembly;

            //找到form配置类
            Type[] types = callerAssembly.GetTypes();
            foreach (Type type in types) {
                object[] attributes = type.GetCustomAttributes(typeof(ToolCreateFormAttribute), false);
                if (attributes.Length > 0) {
                    FormWin = Activator.CreateInstance(type,form);

                    InitUserControl initUserControl=FormWin as InitUserControl;
                    //拿到使用特定的初始化方法
                    string Name = getJsonFile(initUserControl.FormName);
                    if (File.Exists(Name)) {
                        //利用静态内容重构对象内容,数据组装到数据层
                        InitUserControlData initUserControlData = FormWin as InitUserControlData;
                        initUserControlData = Tool.DeserializeFromFile<InitUserControlData>(Name);
                        CopyObject(initUserControl, initUserControlData);
                    }

                    InitUserControlInterface FormInitUserControlInterface = FormWin as InitUserControlInterface;
                    FormInitUserControlInterface.InitUserControlImpl();
                }
            }
        }
        public static void FormClosed() {
            foreach (string item in Functions.Keys) {
                InitUserControlInterface initUserControlInterface = (InitUserControlInterface)Functions[item];
                initUserControlInterface.SaveUserControlImpl();
                InitUserControlData initUserControl = Functions[item] as InitUserControlData;
                SerializeToFile(initUserControl, getJsonFile(initUserControl.FunctionName));
            }
            InitUserControlInterface ForminitUserControlInterface = (InitUserControlInterface)FormWin;
            ForminitUserControlInterface.SaveUserControlImpl();
            InitUserControlData ForminitUserControl = FormWin as InitUserControlData;
            SerializeToFile(ForminitUserControl, getJsonFile(ForminitUserControl.FormName));
        }

        public static string getJsonFile(string Name) {
            string binPath = AppDomain.CurrentDomain.BaseDirectory+ "Serialize\\" + Name + ".json";
            return binPath;
        }

        public static void CopyObject<T,X>(T A, X B)where T:X {
            Type TcurrentType = typeof(T);
            FieldInfo[] Tproperties = TcurrentType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);

            Type XcurrentType = typeof(T);
            FieldInfo[] Xproperties = XcurrentType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);

            foreach (FieldInfo Tproperty in Tproperties) {
                foreach (FieldInfo Xproperty in Xproperties) {
                    if (Tproperty.Name.Equals(Xproperty.Name)) {
                        try {
                            Tproperty.SetValue(A, Xproperty.GetValue(B));
                        } catch (Exception ex) { }
                    }
                }
            }
        }
    }
}
